// js callbacks for index page

x0 = -320;
y0 = -240;

canvas = null;
context = null;  
key = new Array();
FPS = 20;
mx = 320;
my = 0;
level = 0;
shots = new Shots();
ship = new Ship();
//ship.dx = -30;
credits = new Credits();
compass = new Image();
compass.src = "img/compass.png";
compass_dummy = new Image();
compass_dummy.src = "img/compass_dummy.png";
earth = new Image();
earth.src = "img/earth.png";
autofire_interval = 0;
pause = false;
in_input = false; // true if i am in input so ignore wasd commands because i am writing text
aliens = null;
kills = 0;
alien_freeze_time = FPS*1;
//aliens = new Aliens();
//d = new AlienDummies(3);
//aliens.add(d);
nextLevel();

function getCookie(ACookieName) {
  // retrieve cookie value
  if (document.cookie.length>0) {
    c_start = document.cookie.indexOf(ACookieName + "=");
    if (c_start != -1) {
      c_start = c_start + ACookieName.length+1;
      c_end = document.cookie.indexOf(";",c_start);
      if (c_end == -1) 
        c_end = document.cookie.length;
      return unescape(document.cookie.substring(c_start,c_end));
    }
  }
  return "";
}

function onLoad() {
  canvas = document.getElementById('canvas');
	context = canvas.getContext('2d');
	setInterval('onInterval()',1000/FPS);
	send(false);
	// fill in name from cookies
	document.getElementById('name').value = getCookie('name');
}

function onInterval() {
  // periodic update
  if (pause)
    return;
  // utilization counter
  var t1 = new Date().getTime();

  // ship WASD movement, update background if necessary
  if (ship.wasd()) {
    canvas.style.backgroundPosition=(-ship.x)+'px '+(-ship.y)+'px';
  }

  // clear canvas
  context.clearRect(0,0,640,480);

  // earth
  context.save();
  context.translate(-x0-ship.x,-y0-ship.y);
  context.drawImage(earth,-32,-32);
  context.restore();

  // compass
  context.save();
  context.translate(320,240);
  context.rotate(Math.atan2(-ship.y,-ship.x));
  context.globalAlpha = Math.min(0.5,(ship.x*ship.x+ship.y*ship.y)/320/320);
  context.drawImage(compass,-8+20,-8);
  context.globalAlpha = 1.0;
  context.restore();
  
  // compass - first dummy
  if (aliens.aliens.length > 0) {
    context.save();
    context.translate(320,240);
    context.rotate(Math.atan2(aliens.aliens[0].y-ship.y,aliens.aliens[0].x-ship.x));
    //context.globalAlpha = Math.min(0.5,(ship.x*ship.x+ship.y*ship.y)/320/320);
    context.drawImage(compass_dummy,-8+20,-8);
    context.globalAlpha = 1.0;
    context.restore();
  }
  
/*
  FIXME: this doesn't work, it draws to canvas but anything painted remain there despite the fact i cleared canvas in previous step
  context.fillStyle = "rgba(0,0,255,0.5)"; // "+(ship.x*ship.x+ship.y*ship.y)/320/320+")";
  context.moveTo(20, 10); // give the (x,y) coordinates
  context.lineTo(30, 0);
  context.lineTo(20, -10);
  context.lineTo(20, 10);
  context.fill();
*/
    
  // draw game objects
  ship.draw();
  aliens.draw();
  shots.draw();
  credits.draw();
  buttonsDraw();
  
  // level info
  if (aliens.aliens.length == 0) {
    context.font = "16pt courier";
    context.fillStyle = "rgba(0,255,0,1)";
    context.textAlign = "center";
    context.fillText("Level completed",320,220);
    context.fillText("Prepare for level "+(level+1),320,275);
  }
  context.font = "16pt courier";
  context.fillStyle = "rgba(0,255,0,1)";
  context.textAlign = "center";
  context.fillText("Level "+level,320,20);

  // aliens left
  if (aliens.aliens.length > 0) {
    context.font = "12pt courier";
    context.fillStyle = "rgba(0,255,0,0.7)";
    context.textAlign = "center";
    context.fillText(aliens.aliens.length+" aliens",320,40);
  }

  // aliens killed
  if (aliens.aliens.length > 0) {
    context.font = "9pt courier";
    context.fillStyle = "rgba(255,70,70,0.9)";
    context.textAlign = "center";
    context.fillText(kills+" kills",320,55);
  }

  // colisions with objects and shots 
  aliensHit();
  
  // game over?
  if (ship.life <= 0) {
    context.save();
    context.font = "20pt fixed";
    context.textAlign = "center";
    context.fillStyle = "rgba(0,0,0,0.7)";
    context.fillRect(320-150,240-15-10,2*150,2*15+5);
/*
    context.fillStyle = "black";
    context.fillText("You just lost the game",320,240);
    context.fillText("You just lost the game",320-2,240-2);
    context.fillText("You just lost the game",320-2,240+2);
    context.fillText("You just lost the game",320+2,240-2);
    context.fillText("You just lost the game",320+2,240+2); 
    context.fillText("You just lost the game",320-1,240-1);
    context.fillText("You just lost the game",320-1,240+1);
    context.fillText("You just lost the game",320+1,240-1);
    context.fillText("You just lost the game",320+1,240+1);
*/    
    context.font = "20pt fixed";
    context.fillStyle = "rgb(255,0,0)";
    context.fillText("You just lost the game",320,240);
    context.restore();          
  }
  
  // calculate utilization
  var t2 = new Date().getTime();
  var dt = Math.round(100*(t2 - t1)/(1000/FPS));
  if (dt < 10) dt = '0'+dt;

  // statistics
  context.font = "bold 9pt courier";
  context.textAlign = "left";
  context.fillStyle = "#888";
  context.fillText(/* '  S:'+shots.shots.length+'  U:'+*/ dt+'%',4,10);
  context.font = "9pt courier";
}

function onKeyDown(AEvent) {
  // press key
  if (in_input)
    return;
  key[AEvent.keyCode] = true;
//  document.title = AEvent.keyCode+' down '+AEvent.key;
}

function onKeyUp(AEvent) {
  if (in_input)
    return;
  // release key
  key[AEvent.keyCode] = false;
  // pause on/off?
  if (AEvent.keyCode == 80)
    pause = !pause;
  // buying upgrades
  switch (AEvent.keyCode) {
    case 49: buySomething(0); break;
    case 50: buySomething(1); break;
    case 51: buySomething(2); break;
    case 52: buySomething(3); break;
    case 53: buySomething(4); break;
    case 54: buySomething(5); break;
    case 55: buySomething(6); break;
    case 56: buySomething(7); break;
    case 57: buySomething(8); break;
  }
}

function canvasMouseMove(AThis,AEvent) {
  // calculate ship's angle
  if (ship.life <= 0)
    return;
  mx = AEvent.pageX-AThis.offsetLeft;
  my = AEvent.pageY-AThis.offsetTop;
  ship.angle = Math.atan2(240-my,320-mx)-Math.PI/2;
}

function canvasMouseDown(AThis,AEvent) {
  // shoot from my ship
  if (ship.life <= 0)
    return;
  mx = AEvent.pageX-AThis.offsetLeft;
  my = AEvent.pageY-AThis.offsetTop;
//  shots.push(new Shot(320-ship.x,240-ship.y,mx-ship.x,my-ship.y));
//  autofire_enabled = true;
  autofire();
  if (autofire_interval > 0)
    clearInterval(autofire_interval);
  autofire_interval = setInterval('autofire()',60000/ship.rate);
  // detect upgrade buttons
  if (AEvent.button == 0) {
    buttonDetect(mx,my);
  }
}

function canvasMouseUp(AThis,AEvent) {
  // stop shooting
  clearInterval(autofire_interval);
}

last_fire = 0;

function autofire() {
  // autofire
  // prevent abuse
  var lf = new Date().getTime();
  if (lf - last_fire <= 0.9*(60000/ship.rate))
    return;
  last_fire = lf;
  // is player alive?  
  if (ship.life > 0)
    for (var i=0; i<ship.spread; i++)
      shots.push(new Shot(ship.x,ship.y,mx+x0+ship.x,my+y0+ship.y,5+10*i-10*ship.spread/2));
}

function aliensHit() {
  // detect weather aliens was hit by my shots
  // for all 
  for (var d=aliens.aliens.length-1; d>=0; d--) {
    // shrapnels age without contact with shot so they shoudl be removed
    if (aliens.aliens[d].life<=0) {
      aliens.aliens.splice(d,1);
      if (aliens.aliens.length == 0)
        setTimeout("nextLevel()",3000);
      continue;
    }
    var dummy_removed = false;
    var dx = aliens.aliens[d].x;
    var dy = aliens.aliens[d].y;
    // for all shots
    for (var s=shots.shots.length-1; s>=0; s--) {
      if (dummy_removed)
        break;
      var sx = shots.shots[s].x;
      var sy = shots.shots[s].y;
      // simple distance calculation
      var r = Math.abs(dx-sx)+Math.abs(dy-sy);
      // hit?
      if (r < aliens.aliens[d].size) {
        // shot suck aliens life
        if (shots.shots[s].size > 0)
          aliens.aliens[d].life -= shots.shots[s].speed * shots.shots[s].size;
        //document.title = 'hit by r='+Math.round(r)+' dl='+aliens.aliens[d].life;
        // remove dead aliens
        if (aliens.aliens[d].life <= 0) {
          // add bunch of credits in the place of dead dummy
          credits.explode(aliens.aliens[d].x,aliens.aliens[d].y,aliens.aliens[d].credit);
          // add some shrapnels to alien explosion
          if (aliens.aliens[d].shrapnel > 0)
            aliens.add(new AlienShrapnels(aliens.aliens[d].shrapnel,aliens.aliens[d].x,aliens.aliens[d].y));
          // remove dummy
          dummy_removed = true;
          aliens.aliens.splice(d,1);
          kills++;
          // credits for killed aliens
          ship.credit += ship.credit_multiplier;
          // if we defeated all aliens, start new level
          if (aliens.aliens.length == 0)
            setTimeout("nextLevel()",3000);
        }
        // remove shots because of it's low penetration
        // when hit, decrease their size (we use negative shot size for harmless blood splatter)
        shots.shots[s].size--;
        // slow them down
        shots.shots[s].dx *= 0.9; 
        shots.shots[s].dy *= 0.9; 
      }
      //return;
    }
  }
}

function debug(ALine,AText) {
  // print debug text on n-th line from top
  context.fillStyle = "blue";
  context.fillRect(4,15*ALine,200,15);
  context.fillStyle = "white";
  context.fillText(AText,4,15*ALine+10);
}

function summon(ADummies,AFollowers,ATurrets,AMummies,AFummies,ACannons,ARocks,AStealers,ALaunchers) {
  // summon given amount of each type of alien, used for creating levels
  aliens.add(new AlienDummies(ADummies));
  aliens.add(new AlienFollowers(AFollowers));
  aliens.add(new AlienTurrets(ATurrets));
  aliens.add(new AlienMummies(AMummies));
  aliens.add(new AlienFummies(AFummies));
  aliens.add(new AlienCannons(ACannons));
  aliens.add(new AlienRocks(ARocks));
  aliens.add(new AlienStealers(AStealers));
  aliens.add(new AlienLaunchers(ALaunchers));  
}

function nextLevel() {
  // increment level and create new aliens for that level
  score();
  level++;
  aliens = new Aliens();
  switch (level) {//d  f  t  M  F  C  R  S  L
    //case 1: summon( 0, 0, 0, 0, 0, 1, 0, 0, 4); break; // testing first level
    case 1: summon(10, 0, 0, 0, 0, 0, 0, 0, 0); break;
    case 2: summon(11, 4, 0, 0, 0, 0, 0, 0, 0); break;
    case 3: summon(12, 6, 3, 0, 0, 0, 0, 1, 0); break;
    case 4: summon(13, 8, 4, 4, 0, 0, 0, 1, 0); break;
    case 5: summon(14,10, 5, 5, 5, 0, 0, 2, 0); break;
    case 6: summon(15,12, 6, 6, 6, 6, 0, 2, 1); break;
    case 6: summon(16,14, 7, 7, 7, 7, 7, 3, 2); break;
    // TODO: tune next levels, previous too
    
    // defaul fallback settings
    aliens.add(new AlienDummies(10+level));
    aliens.add(new AlienFollowers(2*level));
    aliens.add(new AlienTurrets(level));
    aliens.add(new AlienMummies(level));
    aliens.add(new AlienFummies(level));
    aliens.add(new AlienCannons(level));
    aliens.add(new AlienRocks(level));
    aliens.add(new AlienStealers(level));
    aliens.add(new AlienLaunchers(level));
  }
}

function readChat(xml) {
  alert('readChat '+xml.readyState);
}

function score() {
  // send score info
  if (level<=0)
    return;
  var request = new XMLHttpRequest();
  if (!request)
    return;
  request.open("POST", 'score.php', true); // asynchronous
  request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
  request.send('name='+document.getElementById('name').value+'&life='+ship.life+'&level='+level+'&kills='+kills+'&aliens='+aliens.aliens.length+'&credit='+ship.credit);
  /*
  TODO: display info in scoreboard
  if (request.status == 200) {
    alert('score: '+request.responseText); //document.getElementById('board').innerHTML = request.responseText;
    setTimeout('document.getElementById("board").style.background = ""',200);
  } else
    alert('Cannot send score info, please try again later!');
  */
}

function send(ASendMessage) {
  // send chat message to: chat.php?name=janko&message=asdf
  document.getElementById('board').style.background = "silver";
  var request = new XMLHttpRequest();
  if (!request) {
    alert('Your browser sucks, piss off!');
    return;
  }
  request.open("POST", 'chat.php', false);
  request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
  if (ASendMessage) 
    request.send('name='+document.getElementById('name').value+'&message='+document.getElementById('message').value);
  else
    request.send(null);
  if (request.status == 200) {
    document.getElementById('board').innerHTML = request.responseText;
    setTimeout('document.getElementById("board").style.background = ""',200);
    // remember name in cookies
    var name = document.getElementById('name').value;
    if (name!='')
      document.cookie = 'name='+name+'; expires=Thu, 2 Aug 2099 20:00:00 UTC; path=/';
  } else
    alert('Cannot send chat message, please try again later!');
}

function dumpScene() {
  // print all objects in scene for debuging
  alert(
    ship.debug()+
    aliens.debug()+
    shots.debug()
  );
}

function aTest() {
  nextLevel();
}


